home *** CD-ROM | disk | FTP | other *** search
-
- REND386 -- A 3-D Polygon Rendering Package for the 386 and 486
- Written by Dave Stampe and Bernie Roehl
-
- LIBRARY Documentation
- Version 2.02 - April 1992
-
- This package contains a library of routines (callable from C) that will
- render 3 dimensional scenes on 386 and 486 based systems with a VGA display.
-
- The package also includes a simple user-interface library with joystick
- support, and a demo program to show what it's capabable of.
-
- The package is designed to be fast. It accomplishes that goal by making
- use of the special instructions that exist only on 386 and 486 processors;
- it will not run on 286s, 8086s or 8088s.
-
- It also requires Turbo C++ or Borland C to link; Turbo C 2.00 seems to
- generate unresolved references.
-
- A NOTE ON SPEED:
-
- Speed is not a straightforward thing to measure. There is a relationship
- between the speed of the processor, the complexity of the scene, and the
- number of frames per second.
-
- With this software, a 512-polygon scene can be rendered at speeds up to
- 14 frames/second on a 486/25; this corresponds to a speed of over 7000
- polys/second.
-
- LICENSING:
-
- These libraries may be freely used to write software for release into the
- public domain. Permission to use these libraries for the production of
- commercial software (including shareware) must be obtained from the authors,
- Bernie Roehl (broehl@sunee.uwaterloo.ca) and Dave Stampe
- (dstampe@sunee.uwaterloo.ca).
-
- Licensing terms will be very, very reasonable.
-
- SOFTWARE DOCUMENTATION
-
- The following sessions describe the various data structures and routines
- that comprise the rend386 package.
-
- SECTION A -- OBJECTS
-
- The following functions deal with OBJECTs. OBJECTs have several properties
- associated with them: a set of vertices, a set of polygons, a name, an
- owner and a set of flags. Each vertex has an x,y,z location in the object's
- native coordinates, and a (probably different) x,y,z location in world
- coordinates. Each polygon has a color value and an array of pointers to the
- vertices that define that polygon.
-
- OBJECT *new_obj(int type, int nv, int np, char *name)
- Creates a new object, with room for up to nv vertices and np polygons.
- The given name is set in the object.
-
- void add_vertex(OBJECT *obj, long x, long y, long z)
- Adds a vertex to the given object, with x,y,z as its coordinates
- in object space.
-
- POLY *add_poly(OBJECT *obj, unsigned color, int npoints)
- Adds a polygon to the given object, with the given color and room
- for up to npoints vertices.
-
- void add_point(OBJECT *obj, POLY *p, int vertnum)
- Adds a point to a polygon. Vertex number vertnum in object obj is
- added to the given polygon. The vertices must be added in a
- "clockwise" order as seen from outside the object.
-
- void delete_obj(OBJECT *obj)
- Deletes the given object and frees all memory associated with it.
-
- long object_bounds(OBJECT *obj, long *x, long *y, long *z)
- Obtains the x,y,z extents of the given object.
-
- void compute_obj(OBJECT *obj)
- Does internal computation of polygon normals, bounding sphere, and
- so forth. Must be called once the object is complete (i.e. all the
- vertices and polygons have been added, and the points comprising
- the polys have been defined) and before the object is rendered.
-
- void set_obj_flags(OBJECT *obj, unsigned char value)
- Sets the object's flags.
-
- unsigned char get_obj_flags(OBJECT *obj)
- Gets the object flags.
-
- The bottom two bits of the flags word are named OBJ_INVIS (which indicates
- that the object is invisible and should not be drawn) and OBJ_HIGHLIGHTED
- (indicating that the object should be drawn highlighted).
-
- void get_obj_info(OBJECT *obj, int *nv, int *np, char *buffer, int maxn)
- Extracts the number of vertices in obj and stores it in *nv, and
- similarly stores the number of polys in obj in *np. If maxn is
- non-zero, the given buffer is filled in with the name of the object
- (if one has been set). The buffer must contain room for up to maxn
- characters.
-
- void get_vertex_info(OBJECT *obj, int vertnum, long *x, long *y, long *z)
- Extracts the x, y and z values of vertex number vertnum in obj.
- This function obtains the coordinates in the object coordinate system.
-
- void get_vertex_world_info(OBJECT *obj, int vertnum, long *x, long *y, long *z)
- Extracts the x, y and z values of vertex number vertnum in obj.
- This function obtains the coordinates in the world coordinate system.
-
- void get_poly_info(OBJECT *obj, int polynum, unsigned *color, int *nverts,
- int *verts, int maxverts)
- Extracts information from polygon number polynum in obj. The color
- parameter is set to the polygon color (see colors.doc for details).
- If maxverts is non-zero, then the array of integers verts is filled
- in with the index numbers of the vertices comprising the polygon.
- No more than maxverts vertices will be stored; if there are more
- than that number of vertices in the object, the rest will be ignored.
-
- void set_poly_color(OBJECT *obj, int polynum, unsigned color)
- Sets the color of polygon number polynum in obj to the given color.
- See colors.doc for details of how the color parameter is interpreted.
-
- void *get_object_owner(OBJECT *obj)
- Returns the owner field of the given object. The owner field is not
- used by the renderer, and is provided for the convenience of the
- application programmer. It might, for example, be a pointer to the
- segment that this object is the representation of (see the section on
- segments for more information).
-
- void set_object_owner(OBJECT *obj, void *owner)
- Sets the object's owner field.
-
- OBJECT *copy_obj(OBJECT *obj, int nverts, int npolys, char *name)
- Makes a copy of the given object, with room for nverts vertices and
- npolys polygons. This is to allow you to add additional vertices
- and polygons using an existing object as a starting point. The name
- field is set in the copy.
-
- void copy_world_to_object(OBJECT *obj)
- Copies the world coordinates of the object into its object coordinates,
- effectively making the object's coordinate system the same as the
- world coordinate system. Rarely used.
-
- void highlight_obj(OBJECT *obj)
- Turns on the HIGHLIGHT bit in the color field of all the polys in the
- given object.
-
- void unhighlight_obj(OBJECT *obj)
- Turns off the HIGHLIGHT bit in the color field of all the polys in the
- given object.
-
- SECTION B -- OBJLISTS
-
- The following functions deal with object lists, or OBJLISTs. An OBJLIST is
- what you pass to the renderer (i.e. you tell it to render a given list of
- objects).
-
- OBJLIST *new_objlist()
- Creates a new object list and returns a pointer to it.
-
- void add_to_objlist(OBJLIST *list, OBJECT *obj)
- Adds an object to an object list.
-
- void remove_from_objlist(OBJLIST *list, OBJECT *obj)
- Removes an object from an object list.
-
- void del_objlist(OBJLIST *list)
- Deletes an object list.
-
- OBJECT *first_in_objlist(OBJECT **objlist)
- Returns a pointer to the first object in a list.
-
- OBJECT *next_in_objlist(OBJECT **objlist, OBJECT *obj)
- Returns a pointer to the next object (after obj) in a list.
-
- OBJECT *prev_in_objlist(OBJECT **objlist, OBJECT *obj)
- Returns a pointer to the previous object (after obj) in a list.
-
- int is_first_in_objlist(OBJECT **objlist, OBJECT *obj)
- Returns non-zero if obj is the first entry in the given list.
-
- int is_last_in_objlist(OBJECT **objlist, OBJECT *obj)
- Returns non-zero if obj is the last entry in the given list.
-
- SECTION C -- VIEWS
-
- In addition to an OBJLIST, the rendering routines need to know about your
- current viewpoint; the VIEW structure contains this information. It has
- three fields (ex, ey, ez) that define the current location of your "eye"
- or "camera" in world coordinates, and another three (pan, tilt and roll)
- that define the "camera's" rotation about the Y (vertical) axis, X
- (horizontal) axis, and Z (forward) axis respectively.
-
- The VIEW also has near/far clipping information in the the hither and yon
- fields (in world coordinates).
-
- (A note about coordinates: X is positive to the right, Y is positive up and
- Z is positive away from you).
-
- There is also a zoom factor, which works like the zoom on a camera.
-
- The angles and zoom factor are all stored as 32-bit (long) integers, but
- are best thought of as floating point numbers multiplied by 65536L. This
- is referred to in this document as "16.16" format (16 bits of integer,
- 16 bits of fraction).
-
- A VIEW also has information about what area on the screen should be used to
- present the scene; these left, right, top and bottom values are in absolute
- screen coordinates. There is also an "aspect ratio" which determines the
- relative size of a non-square pixel.
-
- The world-space coordinates of a single light source are stored in the lx,ly
- an lz fields.
-
- There is also a "flags" field whose bottom bit is set if the objects should
- all be drawn in wire-frame mode rather than as filled polygons. Because no
- explicit edge information is stored in the OBJECT data structures, wireframing
- is actually slower than filled-polys since each edges winds up getting drawn
- twice.
-
- The next two bits (called HIDE_HIGHLIGHTED and HIDE_UNHIGHLIGHTED) determine
- whether highlighted (and/or unhighlighted) objects should be invisible.
-
- Finally, there's a 200 byte "work area" associated with each VIEW.
-
- void compute_view_factors(VIEW *v)
- This function should be called whenever the view has changed; it
- computes internal information based on the values described above.
-
- In addition to all this, there's a global struct called Screeninfo that
- has the minimum and maximum X and Y values, the number of available colors,
- the number of pages, and the screen coordinates of the screen "center".
-
- SECTION D -- MATRICES
-
- A matrix is a 4 by 3 array of long (32-bit) integers. It can best be thought
- of as an upper 3x3 matrix representing rotations, and 3-element bottom row
- vector representing translation. A matrix is used to transform a point or
- an object.
-
- void make_matrix(MATRIX m, long rx, long ry, long rz, long tx, long ty, long tz)
- Fills in a matrix with the appropriate values for rotation and translation.
- The rx, ry and rz values are the rotations around the three axes; these
- values are all in 16.16 format (i.e. a 16-bit integer part and a 16-bit
- fractional part) and are expressed in degrees. To convert from degrees in
- floating-point to this format, just multiply by 65536L. The translation
- values tx, ty and tz are all in 32-bit "world" units.
-
- void matrix_mult(MATRIX a, MATRIX b, MATRIX c)
- Does a pseudo-matrix-multiply. The 'a' matrix is multiplied by the 'b'
- matrix and the result is stored in the 'c' matrix. Note that this is not
- a real matrix multiply; only the top 3x3 matrix is affected. You must deal
- with the bottom 3-element vector separately.
-
- void matrix_point(MATRIX m, long *xp, long *yp, long *zp)
- Applies the given matrix to a point given the addresses of its x,y,z values.
-
- void apply_matrix(OBJECT *obj, MATRIX m)
- Applies the given matrix to all the vertices in the given object,
- generating new world coordinates from the object coordinates.
-
- void matrix_transpose(MATRIX a, MATRIX b)
- Transposes the matrix 'a' into the matrix 'b' (exchanges rows with columns).
-
- void inverse_matrix(MATRIX a, MATRIX b)
- Finds the pseudo-inverse of 'a' and stores it in 'b'. This is not a real
- inverse; it only works for matrices in which the top 3x3 is a rotation
- submatrix and the bottom row is a translation vector.
-
- long isine(long angle)
- Returns the sine of the angle in internal format; the angle is in degrees,
- in 16.16 format. Probably does not need to be called directly.
-
- long icosine(long angle)
- Returns the cosine of the angle in internal format; the angle is in degrees,
- in 16.16 format. Probably does not need to be called directly.
-
- SECTION E -- SEGMENTS
-
- A segment is a piece of an articulated (multi-jointed) figure. Each segment
- has a parent segment; the parent the "root" segment is NULL. Each segment
- has a linked list of children, and each segment has a 'sibling' which
- is the next segment in the parent's linked list of children.
-
- Each segment also has several values associated with it, including the
- position and orientation of the segment relative to its parent (or relative
- to the world coordinate system, for the root object) as well as a name and
- a "representation" which might, for example, be a pointer to an OBJECT.
-
- SEGMENT *new_seg(SEGMENT *parent)
- Creates a new segment, with the given segment as its parent. If the
- 'parent' parameter is NULL, this is a root object.
-
- void seg_setrep(SEGMENT *s, void *rep)
- Sets the 'representation' field of the given segment to the given value.
-
- void *seg_getrep(SEGMENT *s)
- Returns the value of the 'representation' field of the given segment.
-
- void seg_getposition(SEGMENT *s, long *x, long *y, long *z, long *rx,
- long *ry, long *rz)
- Stores the current position of the given segment (relative to its parent)
- in *x, *y and *z; also stores its orientation (in 16.16 format) in *rx,
- *ry and *rz.
-
- char *seg_getname(SEGMENT *s)
- Returns the name of the given segment.
-
- void set_setname(SEGMENT *s, char *name)
- Sets the name of the given segment to the given value; a copy is made.
-
- void rel_move_segment(SEGMENT *obj, long x, long y, long z)
- Performs a relative move of the given segment; x, y and z are the amounts
- to move the segment along each of the three axes. After calling this
- routine, you must at some point call update_segment().
-
- void abs_move_segment(SEGMENT *obj, long x, long y, long z)
- Performs an absolute move of the given segment; x, y and z are the new
- to move the segment along each of the three axes. After calling this
- routine, you must at some point call update_segment().
-
- void rel_rot_segment(SEGMENT *seg, long rx, long ry, long rz)
- Performs a relative rotation of the given segment; x, y and z are the
- angles to rotate the segment along each of the three axes (in 16.16
- format). After calling this routine, you must at some point call
- update_segment().
-
- void abs_rot_segment(SEGMENT *seg, long rx, long ry, long rz)
- Performs an absolute rotation of the given segment; x, y and z are the
- angles to rotate the segment to along each of the three axes (in 16.16
- format). After calling this routine, you must at some point call
- update_segment().
-
- void update_segment(SEGMENT *s)
- Takes the current position and orientation and uses it (and similar
- information from the parent segment, and its parents, and so on) to
- transform the segment's representation.
-
- SEGMENT *find_root_segment(SEGMENT *s)
- Walks up the tree from the given segment and finds the root segment for
- the figure of which the segment is a part.
-
- SEGMENT *parent_segment(SEGMENT *s)
- Returns the parent of the given segment.
-
- SEGMENT *child_segment(SEGMENT *s)
- Returns the child of the given segment.
-
- SEGMENT *sibling_segment(SEGMENT *s)
- Returns the sibling of the given segment.
-
- SEGMENT *copy_segment(SEGMENT *s, long dx, long dy, long dz,
- void *(*copyrep_fn)())
- Makes a copy of the given segment, displaced from the original by
- dx,dy,dz, and uses the given function (if not NULL) to make a copy
- of the original segment's representation and set it as the
- representation of the copy. A pointer to the new segment is returned.
-
- void delete_segment(SEGMENT *s, void (*delrep_fn)())
- Deletes the given segment and frees the memory associated with it; calls
- the given function (if not NULL) to delete any representation associated
- with the given segment.
-
- void attach_segment(SEGMENT *s, SEGMENT *to)
- Attaches the given segment to the given parent ('to'), making it a child
- of that segment.
-
- void detach_segment(SEGMENT *s)
- Detaches the given segment from its parent, and makes it an independent
- segment with no parent. Its children remain attached to it, and other
- siblings are unaffected (i.e. they still descend from the same parent
- that has 'disowned' the given segment).
-
- void seg_set_load_info(SEGMENT *s, char *filename, float sx, float sy,
- float sz, long tx, long ty, long tz)
- Stores the information about the scaling and translation of a loaded
- representation into the SEGMENT struct; this is so we can get it back
- later when it comes time to write the segment information back out to
- a file again.
-
- char *seg_get_load_info(SEGMENT *s, float *sx, float *sy, float *sz, long *tx,
- long *ty, long *tz)
- Retrieves the scaling and translation of a loaded representation from the
- SEGMENT struct, so we can write it out to a file.
-
- SECTION F -- COLORS
-
- Four integers are defined in color16.c or color256.c; they are as follows:
-
- screen_clear_color -- the color to which the screen should be cleared
- wireframe_color -- the color in which to draw wireframe outlines
- highlight_color -- the color in which to highlight (outline) objects
- highest_color -- the highest color available in this mode (15 or 255)
-
- They can be changed in the appropriate colors file to whatever values you
- choose.
-
- Color-related routines are as follows:
-
- set_colors()
- Sets up (initializes) the palette.
-
- reset_colors()
- Does nothing, but could eventually restore old palette.
-
- void read_palette(char *buffer)
- Stores the current palette into the given buffer; the buffer must have
- room for either 16 or 256 three-byte entries.
-
- int user_poly_color(POLY *p, int pcolor)
- Does the mapping of user-specified color values into whatever format
- gets passed to lower-level drawing routines; this is where cosine
- lighting is done, for example.
-
- These routines may be changed at will, but bear in mind that this may make
- color usage incompatable with data files generated elsewhere.
-
- SECTION G -- RENDERING ROUTINES
-
- These routines are the main interface to the renderer.
-
- void setup_render()
- Sets up the internal data structures used by the renderer; should be
- called before doing any other calls to any of the rend386 library
- routines.
-
- void reset_render()
- Frees memory allocated for internal data structures used by the renderer;
- should be called before exiting.
-
- void render(OBJLIST *objlist, VIEW *view)
- Renders all the objects in the given objlist from the given viewpoint,
- writing to the current page (see set_drawpage()).
-
- This next routine can be called by the user part of the renderer code.
-
- int poly_cosine(void *poly)
- Given a pointer to a polygon, returns the cosine of the angle between
- the current light source and the polygon's surface normal; the value
- returned is actually the cosine times 128.
-
- SECTION H -- ROUTINES CALLED BY THE RENDERER
-
- These routines are provided by the user (source in render.c); you can implement
- your own "back end" to the renderer just by rewriting these routines.
-
- void ppoly(int count, int *xcoords, int *ycoords, int color)
- Given an array of x coordinates, an array of y coordinates, a count of the
- number of such coordinate pairs, and a color, this routine will display
- the polygon on the screen.
-
- void user_setup_blitter()
- Sets up the blitter.
-
- void user_reset_blitter()
- Resets the blitter.
-
- void user_box(int x1, int y1, int x2, int y2, int color)
- Draws a box with top left corner (x1,y1) and bottom right corner (x2,y2)
- filled in the given color.
-
- void user_text(int x, int y, int color, char *string)
- Displays a string at (x,y) in the given color.
-
- void user_render_poly(int number, int *xcoords, int *ycoords, int color)
- Similar to ppoly, but at a higher level; lets you intercept calls and
- add features. See render.c for details.
-
- There is also a global flag, an integer called 'wireframe', which, if non-zero,
- will cause all objects to be rendered in wireframe mode. Note that this is
- in general slower than actual filled-polygon rendering, since the absence of
- explicit edge information forces each edge to be drawn twice.
-
- SECTION I -- MISCELLANEOUS ROUTINES
-
- OBJECT *where_screen_pt(int *pol, int *vert, int x, int y)
- Given the x, y location of a point on the screen this routine returns a
- pointer to the object that point is on; if pol is not NULL, it is
- set to be the index in the object of the polygon the cursor is on, and
- if vert is not NULL, it is set to the index of the vertex in the object
- that is nearest to the given point.
-
- SECTION J -- LOWER-LEVEL GRAPHICS ROUTINES
-
- enter_graphics()
- Enter graphics mode.
-
- exit_graphics()
- Exit graphics mode.
-
- void clear_display(int page)
- Clear the given display page.
-
- int set_drawpage(int page)
- Make the given page the 'active' one for drawing.
-
- int set_vidpage(int page, int wait)
- Make the given page the 'visible' one.
-
- void vgabox(int left, int top, int right, int bottom, int color)
- Draw a box on the display at the given location in the given color.
-
- SECTION K -- MOUSE ROUTINES
-
- These routines all go through the mouse driver for reading the mouse position,
- but draw their own cursor (in order to support mode Y graphics).
-
- int mouse_init()
- Initializes the mouse, returns non-zero if one is present.
-
- void mouse_deinit()
- De-initializes the mouse.
-
- int mouse_read(int *x, int *y, unsigned *buttons)
- Reads the current screen position of the mouse into *x and *y, and the
- current button state into *buttons; returns non-zero if the mouse or
- its buttons have changed since the last call.
-
- int mouse_hide()
- Hides the mouse and decrements the mouse flag.
-
- void mouse_show(int page)
- Increments the mouse flag, and displays the cursor if the resulting
- value is zero.
-
- SECTION L -- JOYSTICK ROUTINES
-
- The package provides support for reading a joystick. The following struct
- describes the information associated with a joystick port:
-
- typedef struct {
- int x, y, buttons;
- int cenx, ceny;
- int xrange, yrange;
- long scale;
- int port; /* port number, 0 or 1; -1 means 'unused' */
- } joystick_data;
-
- The x, y and buttons fields are the values read from the joystick. The
- cenx and ceny values are the values of x and y that are read when the joystick
- is centered; the values the application program sees are relative to these
- center values, so (0,0) is a centered stick.
-
- The xrange and yrange values are the maximum values for x and y; the scale
- factor is the ratio of movement on the screen to movement of the joystick.
-
- The value the user sees after a call to joystick_read() is, in the case of
- x, ((x_as_read - cenx) * scale)/xrange.
-
- The port value specifies which of the two possible joysticks this structure
- corresponds to.
-
- int joystick_check()
- Checks for the presence of one or two joysticks; the returned value has
- the low-order bit set if joystick 1 is present, and the next higher bit
- set if joystick 2 is present.
-
- void joystick_init(joystick_data *joy, int port)
- Initializes the joystick on the given port (0 or 1)
-
- void joystick_setscale(joystick_data *joy, int value)
- Sets the scale factor for the given joystick
-
- void joystick_scale(joystick_data *joy, int dir)
- Used for joystick calibration; should be called with dir = 0 and joystick
- forward and to the left, then again with dir = 1 and joystick backward and
- to the right. This sets the xrange and yrange values for you.
-
- int joystick_read(joystick_data *joystick)
- Reads the current values of the specified joystick.
-
- void joystick_quit()
- De-initializes joystick processing (current does nothing)
-
- SECTION M -- POINTER ROUTINES
-
- Primitive support is provided for 3-dimensional pointing devices. The file
- pointer.c contains a set of routines that map the movement of a standard
- mouse into three-space; horizontal is X, vertical is Y, and vertical with the
- right-hand button down is Z. If you have a "real" 3D pointing device (e.g.
- PowerGlove) you can rewrite the routines in pointer.c to make use of it.
-
- The following structure is used to return information about the 3D pointer:
-
- typedef struct {
- long x, y, z; /* location in world coordinates */
- long pan, tilt, roll; /* orientation around x, y, z */
- unsigned buttons; /* 16 bits */
- unsigned gesture; /* for future expansion */
- int port; /* in case we need this */
- long sx, sy, sz; /* scaling factors */
- int flex[16]; /* up to 16 words of flexion information */
- } POINTER;
-
- The x, y and z values are the location of the pointer in world coordinates.
- The pan, tilt and roll are the rotation of the pointer in 16.16 format.
- The buttons represent up to 16 buttons, each of which is down or up; in the
- case of the powerglove, this may correspond to one byte of finger information
- and one byte of button information (for example).
-
- The port value is used in case multiple 3D pointing devices are available.
-
- The scaling values are used to alter the movement of the pointer relative
- to that of the pointing device.
-
- The 16 words of flexion information are provided for devices that provide
- more detailed information about joint angles; the gesture field is provided
- for those systems that support gesture recognition.
-
- pointer_init(int port, POINTER *pointer)
- Initializes the pointing device on the given port; returns non-zero if
- a device is found, zero otherwise.
-
- pointer_read(POINTER *pointer)
- Reads the given pointer, updating the fields in the given struct, and
- returning non-zero if the pointer has changed state (location,
- orientation or buttons) since the last call to pointer_read().
-
- void pointer_scale(POINTER *pointer, long sx, long sy, long sz)
- Sets the scaling for the pointer x, y, and z values.
-
- void pointer_quit(POINTER *pointer)
- De-initializes the given pointing device.
-
- void pointer_move(POINTER *pointer, long x, long y, long z)
- Sets the current position of the pointer in world coordinates; all
- subsequent movements of the pointing device will be relative to this
- position.
-
- SECTION N -- USER-INTERFACE ROUTINES
-
- These routines allow you to provide a simple user interface.
-
- void neatbox(int w, int h, int *x, int *y)
- Displays a neat-looking box of height h and width w, centered on the
- screen. The *x and *y values are set to the computed top-left corner
- of the box.
-
- void poptext(char *text[])
- Pops up text box on the screen; the 'text' parameter is an array of
- strings, the last of which is NULL.
-
- void popmsg(char *msg)
- Pops up a one-line message in a box centered on the screen
-
- unsigned askfor(char *prompt, char *buff, int n)
- Prompts the user to enter a string; buff must contain room for up to n
- characters plus a null byte to terminate the string.
-
- SECTION O -- PLG FILE I/O ROUTINES
-
- The ".plg" file format is described in plg.doc; it is not tightly coupled to
- the rest of the renderer software.
-
- OBJECT *load_plg(FILE *in)
- Loads a .plg file and returns a pointer to the newly-created OBJECT.
- The global variable load_err will be set to a non-zero value if there
- was a problem loading the file. As the file is loaded, it is first
- scaled by the current scaling factor and then shifted by the current
- x,y,z offset.
-
- void set_loadplg_offset(long x, long y, long z)
- Specifies the x,y,z offset to use; see figure.doc for details.
-
- void set_loadplg_scale(float x, float y, float z)
- Specifies the x,y,z scaling to use; see figure.doc for details.
-
- save_plg(OBJECT *obj, FILE *out)
- Saves the given object as a .plg file.
-
- SECTION P -- FIG FILE I/O ROUTINES
-
- A figure file consists of a set of segments. See figure.doc for details.
- The format of a figure file is not tightly coupled to the rest of the
- renderer.
-
- SEGMENT *readseg(FILE *in, SEGMENT *parent)
- Allocates a new segment, with the given parent, and reads a segment
- description into that segment. If the file contains nested segments,
- readseg will recursively call itself to load them. See figure.doc for
- more information. The global integer variable readseg_err will be set
- to a non-zero value if an error was encountered during loading.
-
- void set_readseg_objlist(OBJLIST *objlist)
- Sets the given object list as the one to add newly-loaded representations
- to.
-
- writeseg(FILE *out, SEGMENT *s, int level)
- Writes the given segment out to a file; 'level' is used to provide
- levels of indentation, since writeseg calls itself recursively. In
- general, root segments should be written out with level = 0.
-
- SECTION Q -- PCX FILE I/O ROUTINES
-
- These routines are only available in 256 color mode, and allow you to read
- and write .PCX files (PC-Paintbrush format).
-
- load_pcx(FILE *in, int page)
- Load a 320x200x256 .PCX image from the given file onto the given
- display page.
-
- int save_pcx(FILE *out, int page)
- Save a 320x200x256 .PCX image into the given file from the given
- display page.
-
- THE FUTURE:
-
- This rendering package is intended to be the foundation for a wide range
- of applications. Further developments will include replacing the polygon
- blitter with a scan-line based routine; this will not have much effect on
- the speed, but will eliminate the occasional rendering errors that the
- present Z-depth sorting approach can produce.
-
- For further information about the package, feel free to contact us:
-
- Bernie Roehl (broehl@sunee.waterloo.edu)
- Dave Stampe (dstampe@sunee.waterloo.edu)
-
- Note that at some point in the future, sunee.waterloo.edu will become
- sunee.uwaterloo.ca (the ".ca" stands for CAnada, not CAlifornia!)
-
- The major contribution others can make to the project at this stage is
- to write converters from other polygon formats to OFF. In particular,
- a DXF to OFF converter would let us create objects with a CAD package.
-
- OFF is a reasonably good, open format that encodes author/copyright
- information along with geometry and colors. While it's a bit of a
- nuisance to parse, it's very easy to generate.
-
- Two of our data files were converted from OFF files using off2plg: the bishop
- and the banana. Below is the author/copyright information from their .aoff
- files:
-
- name bishop8
- description chess piece - bishop
- author Randy Brown, brown@cs.unc.edu
- copyright (c) Randy Brown, OK to distribute if copyright/author appears
-
- name banana
- description Banana made on Frank Crow's U. Utah surface design system
- copyright (c) Ohio State Univ. - ok to distribute if copyright appears
-
- That's it. Please direct any questions to broehl@sunee.waterloo.edu or
- dstamp@serv1.waterloo.edu, or join the mailing list. To join the list,
- send mail to rend386-request@sunee.uwaterloo.ca (the list itself is just
- rend386@sunee.uwaterloo.ca).
-
-